package com.mycompany.ui.panel;


import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.springframework.beans.factory.annotation.Autowired;

import com.mycompany.config.Injector;
import com.mycompany.model.Provincia;
import com.mycompany.model.Regione;
import com.mycompany.model.User;
import com.mycompany.service.ProvinciaRegioneService;
import com.mycompany.service.UserService;
import com.mycompany.window.MyWindow;
import com.mycompany.window.SubWindowUI;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.fieldgroup.BeanFieldGroup;
import com.vaadin.data.fieldgroup.FieldGroup;
import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
import com.vaadin.data.fieldgroup.PropertyId;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.event.Action;
import com.vaadin.event.Action.Handler;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.server.FileResource;
import com.vaadin.server.Resource;
import com.vaadin.server.VaadinService;
import com.vaadin.shared.ui.combobox.FilteringMode;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.Embedded;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.HorizontalSplitPanel;
import com.vaadin.ui.Image;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Notification.Type;
import com.vaadin.ui.Table;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Button.ClickEvent;


public class UserPanel extends VerticalLayout {
	
	//@PropertyId("nome")
	private TextField nomeField = new TextField ("Nome");
	//@PropertyId("cognome")
	private TextField cognomeField = new TextField ("Cognome");
	//@PropertyId("codiceFiscale")
	private TextField codiceFiscaleField = new TextField("CodiceFiscale");
	//@PropertyId("email")
	private TextField emailField = new TextField("Email");
	//@PropertyId("indirizzo.via")
	private TextField comuneField = new TextField("comune");
	
	//@PropertyId("indirizzo.numeroCivico")
	private TextField numeroCivicoField = new TextField("numeroCivico");
	private TextField viaField = new TextField("Via");
	
	private Table table = new Table();
	private MyWindow window;

	private HorizontalSplitPanel horizontalSplitPanel;

	private BeanItemContainer<User> tableContainer;
	
	private FieldGroup fieldGroup;
	private Action actionDelete = new Action("Delete");
	private int code = 1;
	private static final int  MAX_PAGE_LENGHT = 15;
	
	//Componenti per la gestione delle due comboBox
	private BeanItemContainer<Regione> regioneContainer = new BeanItemContainer<Regione>(Regione.class);

	
	
	@PropertyId("indirizzo.regione")
	private ComboBox regioneBox = new ComboBox("Regione");
	@PropertyId("indirizzo.provincia")
	private ComboBox cittaBox = new ComboBox("Città");
	
	private String pathImmagineUtente = VaadinService.getCurrent().getBaseDirectory().getAbsolutePath()+"/uploads/prova.jpg";
	private Image immagineUtente ;
	private Embedded immagineEmbedded;
	
	@Autowired
	UserService userService;
	
	@Autowired
	ProvinciaRegioneService provinciaRegioneService;
		
	public UserPanel() {
		Injector.inject(this);
		
		// TODO Auto-generated constructor stub
		buildLayout();
		initTable();
		initComboBoxes();
		addComponent(horizontalSplitPanel);
		setSizeFull();
	
	}






	private void buildLayout() {
		// TODO Auto-generated method stub
		horizontalSplitPanel = new HorizontalSplitPanel();
		horizontalSplitPanel.setFirstComponent(table);
		horizontalSplitPanel.setSecondComponent(createFormUser());
		horizontalSplitPanel.setSplitPosition(70,Unit.PERCENTAGE);
		horizontalSplitPanel.setSizeFull();
	}

	private void initTable() {
		// TODO Auto-generated method stub
		tableContainer = new BeanItemContainer<User>(User.class);
		table.setContainerDataSource(tableContainer);
		tableContainer.addNestedContainerProperty("indirizzo.provincia");
		tableContainer.addNestedContainerProperty("indirizzo.regione");
		fillTableContainer();
        table.setVisibleColumns(new Object[] {"nome", "cognome", "codiceFiscale", "email","indirizzo.provincia","indirizzo.regione"});
        table.setColumnHeaders(new String [] {"nome", "cognome", "codiceFiscale", "email","provincia","regione"});
        
        
		table.setSelectable(true);
		table.setSizeFull();
		
		
		table.addItemClickListener(new ItemClickListener() {
			
			@Override
			public void itemClick(ItemClickEvent event) {
				// TODO Auto-generated method stub
				if(event.isDoubleClick()){
					
					BeanItem<User> beanUser = (BeanItem<User>) event.getItem();
					User userToModify = beanUser.getBean();
				
					fieldGroup.setItemDataSource(event.getItem());
					regioneBox.select(userToModify.getIndirizzo().getRegione());
					cittaBox.select(userToModify.getIndirizzo().getProvincia());
					
					
					if(userToModify.getImmagine()!=null){
						loadImmagineUtente(userToModify);
						FileResource immagine = new FileResource(new File(pathImmagineUtente));
				
						
						
						immagineEmbedded.setSource(immagine);
						immagineEmbedded.requestRepaint();
						immagineEmbedded.setWidth("100px");
						immagineEmbedded.setHeight("100px");
						
						immagineUtente.setSource(immagine);
						immagineUtente.requestRepaint();
						immagine.setCacheTime(0);
						immagineUtente.setWidth("100px");
						immagineUtente.setHeight("100px");
					}

				}
				
			}
		});
		
		table.addActionHandler(new Handler() {
			
			@Override
			public void handleAction(Action action, Object sender, Object target) {
				// TODO Auto-generated method stub
				if(actionDelete == action){
					final User userToRemove = (User) target;
					tableContainer.removeItem(userToRemove);
					userService.deleteUser(userToRemove);
					Notification.show("Utente Eliminato");
				}
			}
			
			@Override
			public Action[] getActions(Object target, Object sender) {
				// TODO Auto-generated method stub
				return new Action [] {actionDelete};
			}
		});
		
		
	}

	
	private void initComboBoxes() {
		// TODO Auto-generated method stub
		fillRegioneContainer();

		cittaBox.setFilteringMode(FilteringMode.CONTAINS);
		cittaBox.setNullSelectionAllowed(false);
		updateCityBox(regioneContainer.getIdByIndex(0));
		
		regioneBox.setContainerDataSource(regioneContainer);
		regioneBox.select(regioneContainer.getIdByIndex(0));
		regioneBox.setImmediate(true);
		regioneBox.setNullSelectionAllowed(false);
		regioneBox.setItemCaptionPropertyId("name");
		
		
		regioneBox.addValueChangeListener(new ValueChangeListener() {
			
			@Override
			public void valueChange(ValueChangeEvent event) {
				// TODO Auto-generated method stub
				updateCityBox((Regione)regioneBox.getValue());

			}

			
		});
		
	}
	
	private void fillRegioneContainer() {
		// TODO Auto-generated method stub
			for(Regione regione : provinciaRegioneService.findAllRegione())
				regioneContainer.addBean(regione);
	}


	private void updateCityBox(Regione regione) {
		// TODO Auto-generated method stub
		cittaBox.removeAllItems();
		
	
			for(Provincia provincia : regione.getProvincie())
				cittaBox.addItem(provincia);
				cittaBox.select(regione.getProvincie().get(0));
		
	}

	
	private void fillTableContainer() {
		
		// TODO Auto-generated method stub
		for(User user : userService.selectAll())
				tableContainer.addBean(user);
		
	}
	

	
	private Component createFormUser(){
		
		FormLayout formLayout = new FormLayout();
		//Leggo i fields agli attributi
		
		fieldGroup = new BeanFieldGroup<User>(User.class);
		fieldGroup.setItemDataSource(new BeanItem<User>(new User()));
		buildComponentsToAttribute();
		formLayout.addComponent(nomeField);
		formLayout.addComponent(cognomeField);
		formLayout.addComponent(codiceFiscaleField);
		formLayout.addComponent(emailField);
		formLayout.addComponent(viaField);
		formLayout.addComponent(comuneField);
		formLayout.addComponent(numeroCivicoField);
		formLayout.addComponent(regioneBox);
		formLayout.addComponent(cittaBox);
		
		immagineEmbedded = new Embedded();
		immagineUtente = new Image();
		immagineEmbedded.setAlternateText("Non ci sono Immagini");
		immagineUtente.setAlternateText("Non ci sono Immagini");
		
		formLayout.addComponent(immagineEmbedded);
		formLayout.addComponent(createButtonSaveAndAddUser());
		
		
		return formLayout;
		
	}
	
	private void buildComponentsToAttribute() {
		// TODO Auto-generated method stub
		fieldGroup.bind(nomeField, "nome");
		fieldGroup.bind(cognomeField, "cognome");
		fieldGroup.bind(codiceFiscaleField, "codiceFiscale");
		fieldGroup.bind(emailField, "email");
		fieldGroup.bind(viaField, "indirizzo.via");
		fieldGroup.bind(comuneField, "indirizzo.comune");
		fieldGroup.bind(numeroCivicoField, "indirizzo.numeroCivico");
		//fieldGroup.bind(regioneBox, "indirizzo.regione");
		//fieldGroup.bind(cittaBox, "indirizzo.provincia");
		
	}






	private Component createButtonSaveAndAddUser(){
		
		HorizontalLayout horizontalLayout = new HorizontalLayout();
		Button buttonSalva = new Button("Salva");
		Button buttonNuovo = new Button("Nuovo");
		Button buttonInserisciImmagine = new Button ("Inserisci Immagine");
		
		buttonSalva.addClickListener(new Button.ClickListener() {
			
			@Override
			public void buttonClick(ClickEvent event) {
				// TODO Auto-generated method stub
				
				try {
					
					fieldGroup.commit();
					fieldGroup.setBuffered(false);
					BeanItem<User> beanItem = (BeanItem<User>) fieldGroup.getItemDataSource();
					User userToSave = beanItem.getBean();
					userToSave.getIndirizzo().setRegione((Regione)regioneBox.getValue());
					userToSave.getIndirizzo().setProvincia((Provincia)cittaBox.getValue());
					try {
						userToSave.setImmagine(window.getImageToSave());
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					userService.saveUser(userToSave);
					tableContainer.addBean(userToSave);
					table.refreshRowCache();
					Notification.show("Utente Salvato");
					

					
					


					
				} catch (CommitException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					Notification.show(e.getMessage(), Type.ERROR_MESSAGE);
				}
						
			}	
			
		});
		
		
		buttonNuovo.addClickListener(new ClickListener() {
			
			@Override
			public void buttonClick(ClickEvent event) {
				// TODO Auto-generated method stub
				updateCityBox(regioneContainer.getIdByIndex(0));
				regioneBox.select(regioneContainer.getIdByIndex(0));
				fieldGroup.setItemDataSource(new BeanItem<User>(new User()));
			}
		});
			
		buttonInserisciImmagine.addClickListener(new ClickListener() {

			@Override
			public void buttonClick(ClickEvent event) {
				// TODO Auto-generated method stub
				window = new MyWindow();
			}
		});
		
		
		horizontalLayout.addComponent(buttonSalva);
		horizontalLayout.addComponent(buttonNuovo);
		horizontalLayout.addComponent(buttonInserisciImmagine);
		return horizontalLayout;
	}
	
	private void loadImmagineUtente(User user){
		
		File fileTemp = new File(pathImmagineUtente);
		
		
		try {
			FileOutputStream fos = new FileOutputStream(fileTemp);
			try {
				fos.write(user.getImmagine());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	

}
